/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cw.server;

import cw.biz.GameResultBiz;
import cw.biz.LevelBiz;
import cw.biz.PuzzleBiz;
import cw.biz.PuzzleSizeBiz;
import cw.biz.QuestionBiz;
import cw.biz.SubjectBiz;
import cw.biz.UserBiz;
import cw.entity.GameResult;
import cw.entity.Puzzle;
import cw.entity.PuzzleSize;
import cw.entity.Question;
import cw.entity.Subject;
import cw.ulti.CryptoLibrary;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author VinhTC
 */
public class Server extends UnicastRemoteObject implements ServerInterface {

    UserBiz ubiz = new UserBiz();
    LevelBiz levBiz = new LevelBiz();
    SubjectBiz sbjBiz = new SubjectBiz();
    QuestionBiz quesBiz = new QuestionBiz();
    CryptoLibrary cryptor = new CryptoLibrary();
    private static String serverIP = "";
    private static String port = "";
    private static boolean status = false;
    PuzzleBiz puzzBiz = new PuzzleBiz();
    GameResultBiz gameResultBiz = new GameResultBiz();
    SubjectBiz subjectBiz = new SubjectBiz();
    PuzzleSizeBiz puzzSizeBiz = new PuzzleSizeBiz();

    public Server() throws RemoteException {
    }

    public static String getPort() {
        return port;
    }

    public static String getServerIP() {
        return serverIP;
    }

    public void setIP(String ip) {
        this.serverIP = ip;
    }

    public void setPort(String _port) {
        this.port = _port;
    }

    public boolean getStatus() {
        return this.status;
    }

    public static void setStatus(boolean status) {
        Server.status = status;
    }

    public static void main(String args[]) {
        try {

            Server server = new Server();
            String URL = "rmi://" + serverIP + ":" + port + "/FileServer";
            System.out.println(URL);
            LocateRegistry.createRegistry(Integer.parseInt(port));
            Naming.rebind(URL, server);
            status = true;
            System.out.println("Server started...");
            System.out.println("----------------------------------------");
        } catch (RemoteException ee) {
            System.out.println("Khong tao remote object");
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ee);
        } catch (MalformedURLException me) {
            System.out.println("URL khong hop le");
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, me);
        } catch (Exception e) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    /**
     * login
     * @param username
     * @param pass
     * @return
     */
    public boolean login(String username, String pass) {
        return ubiz.login(username, pass);
    }

    /**
     * decrypt
     * @param str
     * @return String of decryption
     * @throws RemoteException
     */
    public String decrypt(String str) throws RemoteException {
        return cryptor.decrypt(str);
    }

    /**
     * encrypt
     * @param str
     * @return String of encryption
     * @throws RemoteException
     */
    public String encrypt(String str) throws RemoteException {
        return cryptor.encrypt(str);
    }

    /**
     * getPuzzleRandom
     * @param levelId
     * @param sizeId
     * @param subjectId
     * @return Puzzle
     * @throws RemoteException
     */
    public Puzzle getPuzzleRandom(int levelId, int sizeId, int subjectId) throws RemoteException {
        try {
            System.out.println("Client connecting to: " + RemoteServer.getClientHost().toString());
            return puzzBiz.getPuzzleRandom(levelId, sizeId, subjectId);
        } catch (ServerNotActiveException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    /**
     * findPuzzleById
     * @param puzzleId
     * @return Puzzle
     * @throws RemoteException
     */
    public Puzzle findPuzzleById(int puzzleId) throws RemoteException {
        return puzzBiz.findPuzzleById(puzzleId);
    }

    /**
     * getLevelById
     * @param levelId
     * @return cw.entity.Level
     * @throws RemoteException
     */
    public cw.entity.Level getLevelById(int levelId) throws RemoteException {
        return levBiz.getLevelById(levelId);
    }

    /**
     * getSubjectById
     * @param sbjId
     * @return Subject
     * @throws RemoteException
     */
    public Subject getSubjectById(int sbjId) throws RemoteException {
        return sbjBiz.getSubjectById(sbjId);
    }

    /**
     * getLevelByName
     * @param levelName
     * @return cw.entity.Level
     * @throws RemoteException
     */
    public cw.entity.Level getLevelByName(String levelName) throws RemoteException {
        return levBiz.getLevelByName(levelName);
    }

    /**
     * findPuzzleByName
     * @param puzzleName
     * @return Puzzle
     * @throws RemoteException
     */
    public Puzzle findPuzzleByName(String puzzleName) throws RemoteException {
        return puzzBiz.findPuzzleByName(puzzleName);
    }

    /**
     * getSubjectByName
     * @param sbjName
     * @return Subject
     * @throws RemoteException
     */
    public Subject getSubjectByName(String sbjName) throws RemoteException {
        return sbjBiz.getSubjectByName(sbjName);
    }

    /**
     * getQuestionByPuzzleId
     * @param puzzleId
     * @return List<Question>
     * @throws RemoteException
     */
    public List<Question> getQuestionByPuzzleId(int puzzleId) throws RemoteException {
        return quesBiz.getQuestionByPuzzleId(puzzleId);
    }

    /**
     * getQuestionByQuestionContent
     * @param quest
     * @return Question
     * @throws RemoteException
     */
    public Question getQuestionByQuestionContent(String quest) throws RemoteException {
        return quesBiz.getQuestionByQuestionContent(quest);
    }

    /**
     * getQuestionBySubjectId
     * @param subjectId
     * @return List<Question>
     * @throws RemoteException
     */
    public List<Question> getQuestionBySubjectId(int subjectId) throws RemoteException {
        return quesBiz.getQuestionBySubjectId(subjectId);
    }

    /**
     *
     * @param sizeId
     * @return
     * @throws RemoteException
     */
    public List<GameResult> getHightScores(int sizeId) throws RemoteException {

        return gameResultBiz.getHightScores(sizeId);
    }

    /**
     * this method to get all Subject
     * @return
     * @throws RemoteException
     */
    public List<Subject> getAllSubject() throws RemoteException {

        return subjectBiz.getAllSubject();
    }

    /**
     * this method use to get all Level
     * @return List Level
     * @throws RemoteException
     */
    public List<cw.entity.Level> getAllLevel() throws RemoteException {
        return levBiz.getAllLevel();
    }

    /**
     * this method use to get all PuzzleSize
     * @return-- List <PuzzleSize>
     */
    public List<PuzzleSize> getAllPuzzleSize() {
        return puzzSizeBiz.getAllPuzzleSize();
    }

    /**
     * getSizeByName
     * @param sizeName
     * @return PuzzleSize
     * @throws RemoteException
     */
    public PuzzleSize getSizeByName(String sizeName) throws RemoteException {
        return puzzSizeBiz.getSizeByName(sizeName);
    }

    /**
     * addResult
     * @param result
     * @return
     * @throws RemoteException
     */
    public boolean addResult(GameResult result) throws RemoteException {
        return gameResultBiz.addResult(result);
    }
}
